package name.luoyong.spring.sample.controller;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import name.luoyong.spring.sample.entity.User;
import name.luoyong.spring.sample.service.UserService;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class UserController {
	
	@Autowired
	private UserService userService;
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	public UserController() {
		System.out.println("****** UserController init *******");
	}
	
	@RequestMapping("/")
	public String home() {
		return "home";
	}
	
	@RequestMapping("/unauthorized")
	public void unauthorized() {}
	
	@RequestMapping("/register")
	public String register(HttpServletRequest request, User user) {
		
		if(request.getMethod().toLowerCase().equals("get")) {
			return "register";
		}
		
		user.setUsername(user.getUsername().trim());
		user.setPassword(user.getPassword().trim());
		user.setCnName(user.getCnName().trim());
		
		if(userService.isExistByUsername(user.getUsername())) {
			request.setAttribute("errorMsg", "This username is already exists. 请换用其它名称。");
			return "forward:/register.jsp";
		}
		
		userService.add(user);
		
		return "redirect:/";
	}
	
	@RequestMapping("/userInfo")
	public String userInfo(HttpSession session, Model model) {
		Subject subject = SecurityUtils.getSubject();
		
		if( !subject.isAuthenticated() && !subject.isRemembered()) {
			return "redirect:/login";
		}
		
		User user = userService.getCurrentUser(session);
		model.addAttribute("user", user);
		return  null;
	}
	
	@RequestMapping("/editUser")
	public String editUser(HttpServletRequest request, User user) {
		Subject subject = SecurityUtils.getSubject();
		
		if( !subject.isAuthenticated() && !subject.isRemembered()) {
			return "redirect:/login";
		}
		
		if(request.getMethod().toLowerCase().equals("get")) {
			userService.getCurrentUser(request);
			return null;
		}
		
		User currentUser = userService.getCurrentUser(request);
		currentUser.setPassword(user.getPassword().trim());
		currentUser.setCnName(user.getCnName().trim());
		userService.update(currentUser);
		
		return null;
	}
	
	private <T> T queryMyObject(String sql, Object[] params, Class<T> objectType) {
		Map<String, Object> map = jdbcTemplate.queryForMap(sql, params);
		T targetObject = null;
		try {
			targetObject = objectType.newInstance();
		} catch (InstantiationException e1) {
			e1.printStackTrace();
			return null;
		} catch (IllegalAccessException e1) {
			e1.printStackTrace();
			return null;
		}
		
		Set<Entry<String, Object>> entries = map.entrySet();
		for(Entry entry : entries) {
			String name = (String) entry.getKey();
			
			String methodName = "set"+name.substring(0, 1).toUpperCase()+name.substring(1);
			Method method = null;
			try {
				method = objectType.getMethod(methodName, entry.getValue().getClass());
			} catch (NoSuchMethodException e) {
				//e.printStackTrace();
				continue;
			} catch (SecurityException e) {
				e.printStackTrace();
				continue;
			}
			
			try {
				method.invoke(targetObject, entry.getValue());
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		
		return (T) targetObject;
	}

}
